using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Base;
using Algorithms;
using Algorithms.Numerical;
using PetriDiagram.Model;

namespace PetriDiagram.Algorithms
    {
    public partial class CoveringTreeForm: Form
        {
        public CoveringTreeForm()
            {
            InitializeComponent();
            }

        public static DialogResult ShowDialog( IntMatrix im, MarkingVector vct,
            PetriNetModel model)
            {
            CoveringTreeForm ctf = new CoveringTreeForm();
            ctf.Matrix = im;
            ctf.Model = model;
            ctf.Vector = vct;
            return ctf.ShowDialog();
            }

        private Vertex _root;

        private MarkingVector _vector;

        public MarkingVector Vector
            {
            get
                {
                return _vector;
                }
            set
                {
                _vector = value;
                BuildTree();
                }
            }

        private IntMatrix _matrix;

        public IntMatrix Matrix
            {
            get
                {
                return _matrix;
                }
            set
                {
                _matrix = value;
                BuildTree();
                }
            }

        private PetriNetModel _model;

        public PetriNetModel Model
        {
            get { return _model; }
            set { this._model = value; }
        }

        private CoveringTreeView _treeView;
        public CoveringTreeView TreeView
            {
            get
                {
                return _treeView;
                }
            }

        private void BuildTree()
            {
            if( _matrix != null && _vector != null && _model != null )
                {
                _root = new CoveringTree().Build( _matrix, _vector, _model );
                _treeView = new CoveringTreeView( _root );
                this.SuspendLayout();
                this.pictureBox1.Width = _treeView.GetWidth() * CoveringTreeUtils.UnitWidth
                    + CoveringTreeUtils.CellWidth;
                this.pictureBox1.Height = _treeView.GetHeight() * CoveringTreeUtils.UnitHeight
                    +CoveringTreeUtils.CellHeight;
                this.ResumeLayout();
                }
            }

        private void pictureBox1_Paint( object sender, PaintEventArgs e )
            {
            

            if( _root == null )
                return;

            _treeView.Print( e.Graphics );


            //int position = 0;

            //Stack<KeyValuePair<int, Vertex>> q = new Stack<KeyValuePair<int, Vertex>>();
            //q.Push( new KeyValuePair<int,Vertex>(0,_root ));
            //while( q.Count > 0 )
            //    {
            //    KeyValuePair<int, Vertex> kvp = q.Pop();
            //    Vertex current = kvp.Value;
            //    int lvl = kvp.Key;
            //    e.Graphics.DrawString( current.Marking.ToString(), new Font("Arial",8),  new SolidBrush( Color.Red ), lvl * 10, position * 10 );

            //    foreach( Vertex v in current.Children )
            //        q.Push( new KeyValuePair<int, Vertex>( lvl + 1, v ) );

            //    position++;
            //    }

            }

        private void button1_Click( object sender, EventArgs e )
            {
            this.Close();
            }

        private void toolTip1_Popup( object sender, PopupEventArgs e )
            {
            //if( toolTip1.GetToolTip( this.pictureBox1 ) == null )
            //    e.Cancel = true;
            }

        //private void pictureBox1_MouseMove( object sender, MouseEventArgs e )
        //    {
        //    toolTip1.Tag = e;
        //    toolTip1.Show( "", this.pictureBox1, e.Y, e.X, 5000 );
            
        //    }

        //private void toolTip1_Popup( object sender, PopupEventArgs e )
        //    {
        //    string result = GetMarkingFromPosition( toolTip1.Tag as MouseEventArgs );
        //    if( result == null )
        //        e.Cancel = true;
        //    else
        //        toolTip1.ToolTipTitle = "Marking: " + result;
        //    }

        private string GetMarkingFromPosition( MouseEventArgs mouseEventArgs )
            {
            return GetMarkingFromPosition( _treeView.GetRoot(), mouseEventArgs.X, mouseEventArgs.Y );
            }

        private string GetMarkingFromPosition( VertexView node, int posx, int posy )
            {
            int x = ( int )( node.Pos_x * CoveringTreeUtils.UnitWidth );
            int y = ( int )( node.Pos_y * CoveringTreeUtils.UnitHeight );
            if( posx >= x && posx <= x + CoveringTreeUtils.CellWidth && 
                posy >= y && posy <= y + CoveringTreeUtils.CellHeight )
                return node.ReferencedVertex.Marking.ToString();
            else
                {
                string result = null;
                foreach( VertexView vv in node.Children )
                    {
                    result = GetMarkingFromPosition( vv, posx, posy );
                    if( result != null )
                        return result;
                    }

                }
            return null;
            }

        private void pictureBox1_MouseMove( object sender, MouseEventArgs e )
            {
            toolTip1.SetToolTip( this.pictureBox1, GetMarkingFromPosition( e ) );
            }
        }
    }